import { Modal } from '@opentiny/vue';
import { ref, onScopeDispose } from 'vue';
import type { Ref } from 'vue';

// 请求状态类型
type RequestStatus = 'idle' | 'pending' | 'success' | 'error';

// 请求配置类型
interface ApiConfig {
  // 请求唯一标识（可选）
  uniqueId?: string;
  // 请求超时时间（毫秒）
  timeout?: number;
  // 是否立即执行
  immediate?: boolean;
  // 请求头
  headers?: Record<string, string>;
  // 请求参数
  params?: Record<string, any>;
  // 响应数据类型
  responseType?: 'json' | 'text' | 'blob' | 'arraybuffer';
  // 取消请求
  signal?: AbortSignal;
  // 是否请求错误时提示
  isErrorTip?: boolean;
  // 是否请求成功时提示
  isSuccessTip?: boolean;
  // 取消请求的回调函数
  onCancel?: (reason: string) => void;
  // 请求成功的回调函数
  onSuccess?: (data: any) => void;
  // 请求失败的回调函数
  onError?: (error: any) => void;
}

// API 函数类型
type ApiFunction<TParams> = (params: TParams, config?: Record<string, any>) => Promise<any>;

// 返回值类型
interface UseApiReturn<TData, TParams> {
  // 响应数据
  data: Ref<TData | null>;
  // 错误信息
  error: Ref<any | null>;
  // 请求状态
  status: Ref<RequestStatus>;
  // 是否正在加载
  loading: Ref<boolean>;
  // 执行请求函数
  run: (params?: TParams, config?: ApiConfig) => Promise<void>;
  // 取消当前请求
  cancel: (reason?: string) => void;
  // 重置状态
  reset: () => void;
}

// 生成唯一 ID
const generateUniqueId = () => {
  return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
};

/**
 * 封装 API 请求的 Vue Composition API Hook
 * @param api API 函数
 * @param initialParams 初始参数
 * @param initialConfig 初始配置
 * @returns
 */
export const useApi = <TData = any, TParams extends Record<string, any> = Record<string, any>>(
  api: ApiFunction<TParams>,
  initialParams?: TParams,
  initialConfig?: ApiConfig
): UseApiReturn<TData, TParams> => {
  // 响应数据
  const data = ref<TData | null>(null) as Ref<TData | null>;
  // 错误信息
  const error = ref<any | null>(null);
  // 请求状态
  const status = ref<RequestStatus>('idle');
  // 加载状态
  const loading = ref(false);
  // AbortController 用于取消请求
  let abortController: AbortController | null = null;
  // 当前请求的唯一 ID
  let currentRequestId: string | null = null;

  /**
   * 执行请求
   * @param params 请求参数
   * @param config 请求配置
   */
  const run = async (params?: TParams, config?: ApiConfig): Promise<void> => {
    let timeoutId: ReturnType<typeof setTimeout> | null = null;
    // 合并参数和配置
    const mergedParams = { ...initialParams, ...(params || {}) } as TParams;
    const mergedConfig = { ...initialConfig, ...(config || {}) } as ApiConfig;
    try {
      // 取消之前的请求（如果有）
      if (abortController) {
        abortController.abort('Request canceled by new request');
      }

      // 创建新的 AbortController
      abortController = new AbortController();

      // 生成新的请求 ID
      currentRequestId = mergedConfig.uniqueId || generateUniqueId();

      // 更新状态
      status.value = 'pending';
      loading.value = true;
      error.value = null;

      // 设置超时
      if (mergedConfig.timeout) {
        timeoutId = setTimeout(() => {
          abortController?.abort('Request timed out');
        }, mergedConfig.timeout);
      }

      // 执行 API 请求
      const response = await api(mergedParams, {
        ...mergedConfig,
        uniqueId: currentRequestId,
        signal: abortController.signal,
      });
      // console.log(response);

      if (response.code && response.code === 200) {
        data.value = response.data;
      } else {
        throw new Error(response.message);
      }

      // 清除超时定时器
      if (timeoutId) clearTimeout(timeoutId);

      // 更新数据
      //   data.value = response.data;
      status.value = 'success';
      loading.value = false;

      // 调用成功回调
      if (mergedConfig.onSuccess) {
        mergedConfig.onSuccess(response.data);
      }
      if (mergedConfig?.isSuccessTip) {
        console.log(11111, response);

        Modal.message({
          status: 'success',
          message: response.message,
          id: 'apiSuccess',
        });
      }
    } catch (err: any) {
      // 清除超时定时器
      if (timeoutId) clearTimeout(timeoutId);

      // 更新错误状态
      error.value = err;
      status.value = 'error';
      loading.value = false;

      if (mergedConfig?.isErrorTip) {
        Modal.message({
          status: 'error',
          message: err.message,
          id: 'apiError',
        });
      }

      // 如果不是主动取消的错误
      if (err.name !== 'AbortError') {
        console.error('API request failed:', err);

        // 调用错误回调
        if (config?.onError) {
          config.onError(err);
        }
      } else {
        // 调用取消回调
        if (config?.onCancel) {
          config.onCancel(err.message || 'Request canceled');
        }
      }
    }
  };

  /**
   * 取消当前请求
   * @param reason 取消原因
   */
  const cancel = (reason: string = 'Request canceled by user') => {
    if (abortController) {
      abortController.abort(reason);

      // 重置状态
      status.value = 'idle';
      loading.value = false;

      // 调用取消回调
      if (initialConfig?.onCancel) {
        initialConfig.onCancel(reason);
      }
    }
  };

  /**
   * 重置所有状态
   */
  const reset = () => {
    data.value = null;
    error.value = null;
    status.value = 'idle';
    loading.value = false;
    abortController = null;
    currentRequestId = null;
  };

  // 组件卸载时取消所有未完成的请求
  onScopeDispose(() => {
    if (abortController) {
      abortController.abort('Component unmounted');
    }
  });

  // 如果配置了立即执行，则在创建时运行
  if (initialConfig?.immediate) {
    run(initialParams);
  }

  return {
    data,
    error,
    status,
    loading,
    run,
    cancel,
    reset,
  };
};
